//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Xml;
using System.IO;
using System.Runtime.Serialization;

namespace Microsoft.Research.DataLayer
{
    [Serializable]
    public class SQLConnection : ConnectionSecure, ISQLManagementServices
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="SQLConnection"/> class.
        /// </summary>
        /// <param name="worker">The worker.</param>
        private SQLConnection(SQLConnectionWorker worker)
            : base((SQLConnectionWorker)(worker == null ? null : worker.Clone()))
        {
            this.StorageSecurity = worker;
        }

        /// <summary>
        /// Creates the specified conn info.
        /// </summary>
        /// <param name="connInfo">The conn info.</param>
        /// <returns></returns>
        public static Connection Create(SQLConnectionParameters connInfo)
        {
            SQLConnectionWorker worker = (SQLConnectionWorker)SQLConnectionWorker.Create(connInfo);
            SQLConnection results = new SQLConnection(worker);
            return results;
        }

        /// <summary>
        /// Creates the trusted.
        /// </summary>
        /// <param name="server">The server.</param>
        /// <param name="database">The database.</param>
        /// <returns></returns>
        public static Connection CreateTrusted(string server, string database)
        {
            SQLConnectionWorker worker = (SQLConnectionWorker)SQLConnectionWorker.CreateTrusted(server, database);
            SQLConnection results = new SQLConnection(worker);
            return results;
        }

        /// <summary>
        /// Creates the user pass.
        /// </summary>
        /// <param name="server">The server.</param>
        /// <param name="user">The user.</param>
        /// <param name="pass">The pass.</param>
        /// <param name="database">The database.</param>
        /// <returns></returns>
        public static Connection CreateUserPass(string server, string user, string pass, string database)
        {
            SQLConnectionWorker worker = (SQLConnectionWorker)SQLConnectionWorker.CreateUserPass(server, user, pass, database);
            SQLConnection results = new SQLConnection(worker);
            return results;
        }

        /// <summary>
        /// Creates a copy of the connection. This should create a separate channel to the
        /// backend, if needed, to ensure multiple requests can be served in parallel.
        /// </summary>
        /// <returns>A new connection to the storage</returns>
        public override Connection Clone()
        {
            SQLConnection results = new SQLConnection((SQLConnectionWorker)this.Worker);
            return results;
        }


        #region ISQLManagementServices Members

        /// <summary>
        /// Gets the database list.
        /// </summary>
        /// <param name="login">The login.</param>
        /// <returns></returns>
        string[] ISQLManagementServices.GetDatabaseList(string login)
        {
            return ((SQLConnectionWorker)Worker).GetDatabaseList(login);
        }

        #endregion

        #region ISerializable Members

        protected SQLConnection(SerializationInfo info, StreamingContext context)
            : base(SQLConnectionWorker.Create(info, context))
        {
            Open();
        }
        /// <summary>
        /// Iserializable interface implementation
        /// </summary>
        /// <returns></returns>
        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            SQLConnectionWorker worker = (SQLConnectionWorker)this.Worker;
            worker.GetObjectData(info, context);
        }

        #endregion
    }

    internal interface ISQLManagementServices
    {
        /// <summary>
        /// Gets the database list.
        /// </summary>
        /// <param name="login">The login.</param>
        /// <returns></returns>
        string[] GetDatabaseList(string login);
    }
}
